
#include "studio_file.h"

#include <fstream>
#include <regex>
#include "encode/studio_encode.h"

namespace sfs = std::filesystem;

// TODO: 需要做些参照解决编码问题 https://blog.csdn.net/qq_36437446/article/details/105279221
// https://blog.csdn.net/hybluck/article/details/112256543
// 为什么用notepad++ 打开时 有些是中文编码(GBK23..)有些是ANSI
//

std::string _wildcard2regex(const std::string &pattern)
{
    std::string regexPattern;
    for (char c : pattern)
    {
        switch (c)
        {
            case '*':
                regexPattern += ".*";
                break;  // * 匹配任意数量的字符
            case '?':
                regexPattern += ".";
                break;  // ? 匹配单个字符
            case '.':
                regexPattern += "\\.";
                break;  // . 需要转义
            case '\\':
                regexPattern += "\\\\";
                break;  // \ 需要转义
            default:
                regexPattern += c;
                break;
        }
    }
    return "^" + regexPattern + "$";  // 确保整个字符串匹配
}

size_t studio_file::read(const std::string &u8path, std::string &content, const size_t &offset, const size_t &len)
{
    size_t ret_read_size = 0;
    content.clear();
    std::fstream input;
#if IS_WIN32
    if (studio_encode::is_utf8(u8path))
    {
        input.open(studio_encode::cxx11_string_wstring(u8path), std::ios::binary | std::ios::in);
    }

#else
    input.open(u8path, std::ios::binary | std::ios::in);
#endif
    if (!input.is_open())
    {
        return ret_read_size;
    }
    input.ignore(std::numeric_limits<std::streamsize>::max());
    size_t file_size = input.gcount();
    input.clear();  //  ignore函数会移动到文件尾部, 需要移动回文件头
    input.seekg(0, std::ios_base::beg);
    if (offset >= file_size)  // 保证读值不为空
    {
        input.close();
        return ret_read_size;
    }
    input.seekg(0, std::ios::beg);
    ret_read_size = AO_MIN(len, file_size - offset);
    content.resize(ret_read_size);

    input.seekg(offset, std::ios::beg);
    input.read(&content[0], ret_read_size);
    input.close();
    return ret_read_size;
}

size_t studio_file::read(const std::string &u8path, unsigned char **content, const size_t &offset, const size_t &len)
{
    size_t read_size = 0;
    if ((*content))  // content 不能有内容
    {
        return read_size;
    }
    std::string s_cont;
    read_size = studio_file::read(u8path, s_cont, offset, len);
    if (read_size)
    {
        *content = (unsigned char *)malloc(read_size);
        if ((*content))
        {
            memcpy((*content), &s_cont[0], read_size);
        }
        else
        {
            read_size = 0;
        }
    }
    return read_size;
}

bool studio_file::read(const std::string &u8path, std::vector<std::string> &lines)
{
    std::fstream input;
#if IS_WIN32
    input.open(studio_encode::cxx11_string_wstring(u8path), std::ios::binary | std::ios::in);
#else
    input.open(u8path, std::ios::binary | std::ios::in);
#endif
    if (input.is_open())
    {
        std::string line;
        while (std::getline(input, line))
        {
            lines.push_back(line);
        }
    }
    else
    {
        return false;
    }
    input.close();
    return true;
}

size_t studio_file::write(const std::string &u8path, const std::string &content)
{
    size_t write_len = 0;
#if IS_WIN32
    std::ofstream ofs_w(studio_encode::cxx11_string_wstring(u8path), std::ios::out | std::ios::binary);
#else
    std::ofstream ofs_w(u8path);
#endif

    if (!ofs_w.is_open())
    {
        return write_len;
    }
    ofs_w.write(content.c_str(), content.size());
    return content.size();
}

size_t studio_file::write(const std::string &u8path, const std::vector<std::string> &lines)
{
    size_t write_len = 0;
#if IS_WIN32
    std::ofstream ofs_w(studio_encode::cxx11_string_wstring(u8path));
#else
    std::ofstream ofs_w(u8path);
#endif
    if (!ofs_w.is_open())
    {
        return write_len;
    }
    for (auto l : lines)
    {
        ofs_w.write(l.c_str(), l.size());
        write_len += l.size();
    }
    return write_len;
}

bool studio_file::writeLine(const std::string &logFilePath, const std::string &data)
{
    std::ofstream logFile(logFilePath, std::ios::out | std::ios::trunc);  // 确保文件被截断
    if (logFile.is_open())
    {
        logFile << data << std::endl;
        return true;
    }
    else
    {
        return false;
    }
}

std::string studio_file::readLine(const std::string &logFilePath)
{
    std::string date;
    if (std::filesystem::exists(logFilePath))
    {
        std::ifstream logFile(logFilePath);
        if (logFile.is_open())
        {
            std::getline(logFile, date);
            return date;
        }
        else
        {
            return date;
        }
    }
    else
    {
        return date;
    }
}
